package com.engine.aviator;

import com.googlecode.aviator.runtime.function.AbstractVariadicFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorType;

import java.util.Arrays;
import java.util.Map;

public abstract class AbstractContextFunction extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        Object params[]=new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if(args[i].getAviatorType().equals(AviatorType.String)){
                String pa = FunctionUtils.getStringValue(args[i], env);
                params[i]=pa;
            }else if(Arrays.asList(AviatorType.BigInt,AviatorType.Long,AviatorType.Double,AviatorType.Decimal).
                     contains(args[i].getAviatorType())
            ){
                Number pa = FunctionUtils.getNumberValue(args[i], env);
                params[i]=pa;
            }else if(args[i].getAviatorType().equals(AviatorType.Boolean)){
                boolean pa = FunctionUtils.getBooleanValue(args[i], env);
                params[i]=pa;
            }else{
                params[i]=args[i].getValue(env);
            }
        }
        Object[] data = new Object[args.length];
        for (int i = 0; i < params.length; i++) {
            Object pobj=params[i];
            if(params[i] instanceof String){
                String paramsStr=(String)params[i];
                if(paramsStr.indexOf(":")>-1){
                    String paname= paramsStr.split(":", 2)[1];
                    String areaName=paramsStr.split(":", 2)[0];
                    if(env.containsKey(areaName)){
                        Map<String,Object> pdata=(Map<String,Object>)env.get(areaName);
                        data[i]=pdata.get(paname);
                    }else if(pobj!=null){
                        data[i]=pobj;
                    }else{
                        data[i]=params[i];
                    }
                }else{
                    if(pobj!=null){
                        data[i]=pobj;
                    }else{
                        data[i]=params[i];
                    }
                }
            }else{
                data[i]=params[i];
            }

        }
        return execute(env,data);
    }

    public abstract AviatorObject execute(Map<String, Object> env,Object ...objs);
}
